using System;
using Framework;
using Game;

namespace Framework.Random
{
    public abstract class RNG
    {
        public readonly int Seed;
        protected RNG() => Seed = 0;
        protected RNG(int seed) => Seed = seed;

        public abstract int NextInt();
        public virtual int NextInt(int max)
            => MathUtil.MapRange(NextInt(), 0, 1, 0, max);
        public virtual int NextInt(int min, int max)
            => MathUtil.MapRange(NextInt(), 0, 1, 0, max);

        public abstract float NextFloat();
        public virtual float NextFloat(int max)
            => MathUtil.MapRange(NextFloat(), 0, 1, 0, max);
        public virtual float NextFloat(float min, float max)
            => MathUtil.MapRange(NextFloat(), 0, 1, min, max);

        public virtual float Normal(float mean = 0, float stdev = 1)
        {
            float u1 = 1.0f - NextFloat(); // (0,1] 避免零值
            float u2 = 1.0f - NextFloat();
            float randStdNormal = MathF.Sqrt(-2.0f * MathF.Log(u1)) * 
                                  MathF.Sin(2.0f * MathF.PI * u2);
            return mean + stdev * randStdNormal;
        }
    }
}